package wiiusej.apptest;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


import sun.font.CreatedFontTracker;
import wiiusej.*;
import wiiusej.apptest.activityTasks.ComClient;
import wiiusej.apptest.activityTasks.EnergyTransmisionTask;
import wiiusej.apptest.activityTasks.Spell;
import wiiusej.connection.ConnectionManager;
import wiiusej.connection.ShareConnectionCell;
import wiiusej.wiiusejevents.GenericEvent;
import wiiusej.wiiusejevents.utils.WiimoteListener;
import wiiusej.wiiusejevents.wiiuseapievents.WiiUseApiEvent;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.spi.RootLogger;

public class WiimoteMain extends Thread{

	private static final int NTHREADS = 150;
	private static BlockingQueue<Spell> eneergyToComClient = new LinkedBlockingDeque<Spell>();
	
	
	
	
	private static final ExecutorService exec = 
		Executors.newFixedThreadPool(NTHREADS);
	
	private static HashMap<Integer, Wiimote> wiimotes;
	
	//Logger	
	private static Logger fileLogger;
	
	static Lock lock  = new ReentrantLock();	
	static Condition condition = lock.newCondition();
	
	
	public static void main(String[] args) {

		//Log configuration
		PropertyConfigurator.configure("log4j.properties");
		fileLogger = Logger.getLogger("main");
		
		//fileWriter is a WiimoteFileWriter which implements the WiimoteListener
		//interface.
		
		fileLogger.debug("Creating Barrier");
		CyclicBarrier barrier = new CyclicBarrier(2);
		
		//WiiUseApiManager.getInstance();
		//Wiimote[] wiimotes = WiiUseApiManager.getWiimotes(1, true);
		fileLogger.debug("Creating Shared Cell");
		ShareConnectionCell cell = new ShareConnectionCell();
				
		
		//COM queue from Connection Manager to WiiuseApiListener
		BlockingQueue<HashMap<Integer, BlockingQueue<GenericEvent>>> connectionToAPI = 
			new LinkedBlockingQueue<HashMap<Integer, BlockingQueue<GenericEvent>>>();
		
		//COM queue from WiiuseApiListener to ConnectionManager - Inform about Disconnection Events
		BlockingQueue<WiiUseApiEvent> apiToConnection = new LinkedBlockingDeque<WiiUseApiEvent>();
		
		//API listener
		WiiUseApiManager controller = new WiiUseApiManager(cell, barrier, lock, condition, 
				connectionToAPI, apiToConnection);
		controller.start();
		
		//Connection Manager
		ConnectionManager connectionManager = new ConnectionManager(exec, cell, barrier, 
				controller, lock, condition, connectionToAPI, eneergyToComClient, apiToConnection);		
		
		connectionManager.start();
		
		//initComClient();
		
	}		
		
	private static void initComClient(){
		
		Runnable clientServer = 
			new ComClient(eneergyToComClient, wiimotes);
		
		exec.execute(clientServer);
		
	}
	
	
}

	
